//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using System;
using System.ComponentModel;
using System.Linq;
using System.Transactions;
using P2.Cuberry.Framework.BOLBase;
using P2.Cuberry.Framework.Helper;
using P2.Cuberry.Framework.Helper.Configuration;
using P2.Cuberry.Modules.SimpleAccounting.FiCheque.DAL;
using P2.Cuberry.Framework.Security;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using P2.Cuberry.Modules.SimpleAccounting.FiTransaction.DAL;

namespace P2.Cuberry.Modules.SimpleAccounting.FiCheque.BusinessEntities
{
    public class FiCheque : BizObject, INotifyPropertyChanged
    {

        #region TemporaryStorage
        public static List<FiCheque> TemporaryStorage = new List<FiCheque>();
        #endregion


        #region Members

        //++KeyID
        int _fiChequeID = -1;
        public int FiChequeID
        {
            get { return _fiChequeID; }
            protected set
            {
                if (_fiChequeID != value)
                {
                    _fiChequeID = value;
                }
            }
        }

        //Add++
        int _fiscalYearID = -1;
        public int FiscalYearID
        {
            get { return _fiscalYearID; }
            set
            {
                if (value != _fiscalYearID)
                {
                    _fiscalYearID = value;
                    Modified = true;
                }
            }
        }

        decimal? _chequeNo = null;
        public decimal? ChequeNo
        {
            get { return _chequeNo; }
            set
            {
                if (value != _chequeNo)
                {
                    _chequeNo = value;
                    Modified = true;
                }
            }
        }

        string _bank = String.Empty;
        public string Bank
        {
            get { return _bank; }
            set
            {
                if (value != _bank)
                {
                    _bank = value;
                    Modified = true;
                }
            }
        }

        string _myBank = String.Empty;
        public string MyBank
        {
            get { return _myBank; }
            set
            {
                if (value != _myBank)
                {
                    _myBank = value;
                    Modified = true;
                }
            }
        }

        DateTime? _valueDate = DateTime.Now;
        public DateTime? ValueDate
        {
            get { return _valueDate; }
            set
            {
                if (value != _valueDate)
                {
                    _valueDate = value;
                    Modified = true;
                }
            }
        }

        decimal? _amount = 0;
        public decimal? Amount
        {
            get { return _amount; }
            set
            {
                if (value != _amount)
                {
                    _amount = value;
                    Modified = true;
                }
            }
        }

        int? _fiTransactionID = null;
        public int? FiTransactionID
        {
            get { return _fiTransactionID; }
            set
            {
                if (value != _fiTransactionID)
                {
                    _fiTransactionID = value;
                    Modified = true;
                }
            }
        }

        string _note = String.Empty;
        public string Note
        {
            get { return _note; }
            set
            {
                if (value != _note)
                {
                    _note = value;
                    Modified = true;
                }
            }
        }


           

        //DDL++
        int? _currencyID = null;
        public int? CurrencyID
        {
            get { return _currencyID; }
            set
            {
                if (value != _currencyID)
                    _currencyID = value;
                Modified = true;
            }
        }

        public XConfigCurrency XConfigCurrency
        {
            get
            { return BusinessEntities.XConfigCurrency.GetItem(this.CurrencyID.GetValueOrDefault(-1)); }
        }


        public FiAccount.BusinessEntities.FiFiscalYear FiscalYear
        {
            get
            {
                return FiAccount.BusinessEntities.FiFiscalYear.GetItem(this.FiscalYearID);
            }
        }
        

        public ObservableCollection<FiTransaction.BusinessEntities.FiTransactionItem> GetDataofTransactionitem(int fichequeID, bool? credit)
        {
            try
            {
                ObservableCollection<FiTransaction.BusinessEntities.FiTransactionItem> objdata = new ObservableCollection<FiTransaction.BusinessEntities.FiTransactionItem>();
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);

                List<int> lsTransactionItemID = new List<int>();
                using (FiChequeDataContext db = new FiChequeDataContext(connectionString))
                {
                    lsTransactionItemID = db.FiChequeToFiTransactionItem.Where(c => c.FiChequeID == fichequeID).Select(c => c.FiTransactionItemID).ToList<int>();

                }

                FiTransaction.BusinessEntities.FiTransactionItem obj = new FiTransaction.BusinessEntities.FiTransactionItem();


                if (credit == true)
                {
                    objdata = obj.GetTransactionItemsForHeaderusingCheque(lsTransactionItemID, true, fichequeID);
                }
                else
                {
                    objdata = obj.GetTransactionItemsForHeaderusingCheque(lsTransactionItemID, false, fichequeID);
                }
                return objdata;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "FiTransactionItem", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        //public decimal DebitTransactionSum
        //{
        //    get
        //    {
        //        if (DebitttransactionItem != null && DebitttransactionItem.Count > 0)
        //        {
        //            decimal summary = 0;
        //            foreach (var tempItem in DebitttransactionItem)
        //            {
        //                summary += tempItem.FiAccountAmountDebit;
        //            }                   
        //            return summary;
        //        }
        //        else
        //        {
        //            return 0;
        //        }
        //    }
        //}


        //public decimal CreditTransactionSum
        //{
        //    get
        //    {
        //        if (CredittransactionItem != null && CredittransactionItem.Count > 0)
        //        {
        //            decimal summary = 0;
        //            foreach (var tempItem in CredittransactionItem)
        //            {
        //                summary += tempItem.FiAccountAmountCredit;
        //            }
        //            return summary;
        //        }
        //        else
        //        {
        //            return 0;
        //        }
        //    }
        //}


        //end
        #endregion


        #region Computed Properties
        //DDL++
        public string XConfigCurrencyCur 
        {
            get
            {
                if (this. XConfigCurrency != null)
                    return this.XConfigCurrency.XConfigCurrencyCur; 
                else
                    return ""; 
            }
        }



        #endregion


        #region Constructors

        public FiCheque()
        {
            Modified = false;
        }
        public FiCheque(int keyFiChequeID)
        {
            this._fiChequeID = keyFiChequeID;
            FillMyObject();
            Modified = false;
        }
        public FiCheque(DAL.FiCheque fiCheque)
        {
            Load(fiCheque);
          
        }
        #endregion


        #region Read Operations

        //load an existing Instance
        public void Load(int keyFiChequeID)
        {
            FiChequeID = keyFiChequeID;
            if (keyFiChequeID >= 0)
            {
                FillMyObject();
             
            }
            else
            {
                Load(null);                
            }
            Modified = false;
        }


        //Add++ //DDL++
        public void Load(DAL.FiCheque fiCheque)
        {
            if (fiCheque != null)
            {
                this.FiChequeID = fiCheque.FiChequeID;
                
                this.FiscalYearID = fiCheque.FiscalYearID;
                this.ChequeNo = fiCheque.ChequeNo;
                this.Bank = fiCheque.Bank;
                this.MyBank = fiCheque.MyBank;
                this.ValueDate = fiCheque.ValueDate;
                this.Amount = fiCheque.Amount;
                this.FiTransactionID = fiCheque.FiTransactionID;
                this.Note = fiCheque.Note;                
                this.CurrencyID = fiCheque.CurrencyID;                
                
                //Default Fields                
                this.CreatedBy = fiCheque.CreatedBy;
                this.CreatedOn = fiCheque.CreatedOn;
                this.EditedBy = fiCheque.EditedBy;
                this.EditedOn = fiCheque.EditedOn;
                this.Timestamp = fiCheque.TStamp;
                this.StatusID = fiCheque.StatusID.GetValueOrDefault(P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus.GetInitialStatus(this.EntityName).StatusID);

              
            }
            else
            {
                this.FiChequeID = -1;
                this.FiscalYearID = -1;
                this.ChequeNo = null;
                this.Bank = String.Empty;
                this.MyBank = String.Empty;
                this.ValueDate = null;
                this.Amount = 0;
                this.FiTransactionID = null;
                this.Note = String.Empty;                
                this.CurrencyID = null;

                //Default Fields
                this.CreatedBy = String.Empty;
                this.EditedBy = String.Empty;
                P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus initStatus = P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus.GetInitialStatus(this.EntityName);
                this.StatusID = initStatus.StatusID;
            }
            Modified = false;
        }
        internal P2TransactionMessage FillMyObject()
        {
            P2TransactionMessage tMsg = new P2TransactionMessage();            
            if (this._fiChequeID < 0)
            {
                Load(this._fiChequeID);
                
                return tMsg;
            }

            try
            {
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (FiChequeDataContext db = new FiChequeDataContext(connectionString))
                {
                    var xElements = from xElement in db.FiCheque
                                    where xElement.FiChequeID == this._fiChequeID
                                    select xElement;

                    foreach (var xElementx in xElements)
                    {
                        Load(xElementx);
                    }
                }

                tMsg.TransactionStatus = "green";
                tMsg.MessageText = "TMsg_FillMyObjectSuceeded";
            }
            catch (Exception ex)
            {
                tMsg.TransactionStatus = "red";
                tMsg.MessageText = "Error_Error";
                tMsg.MessageFreeText = ex.Message;
                P2ExceptionHandler.LogException(ex, this);
            }            

            this.MessageStack.Add(tMsg);
            return tMsg;

        }
        #endregion


        #region Update Operations

        //Add++
        public P2MessageStack InsertAndUpdate(P2MessageStack MessageStack, bool checkDoublicate)
        {
            MessageStack.AddRange(this.Validator.Validate(this));

            try
            {
                if (MessageStack.StatusMessage.MessageStatus == P2ValidationStatus.green || MessageStack.StatusMessage.MessageStatus == P2ValidationStatus.white || (MessageStack.StatusMessage.MessageStatus == P2ValidationStatus.yellow && P2Validator.YellowErrorDialog.AskSave(MessageStack)))
                {
                    MessageStack.Clear();
                    if (this.FiTransactionID.HasValue && this.FiTransactionID.Value < -1)
                    {
                        // if FiTransactionID < -1 => unsaved item, store in temporary storage
                        var tempItem = TemporaryStorage.FirstOrDefault(it => it.FiTransactionID == this.FiTransactionID);
                        if (tempItem != null)
                        {
                            // existing item, do nothing
                        }
                        else
                        {
                            TemporaryStorage.Add(this);

                        }
                    }
                    else
                    {
                        string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);

                        using (DAL.FiChequeDataContext db = new DAL.FiChequeDataContext(connectionString))
                        {
                            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
                            {
                                //Add++ //DDL++ //--> Set it to starting status.
                                if (this.StatusID == -1) this.StatusID = 170501;

                                if (string.IsNullOrEmpty(this.CreatedBy)) this.CreatedBy = User.Current.UserID;
                                this.EditedBy = User.Current.UserID;

                                DAL.FiCheque editedItem;
                                if (this.FiChequeID < 0)
                                {
                                    editedItem = new DAL.FiCheque()
                                    {
                                        FiscalYearID = this.FiscalYearID,
                                        ChequeNo = this.ChequeNo,
                                        Bank = this.Bank,
                                        MyBank = this.MyBank,
                                        ValueDate = this.ValueDate,
                                        Amount = this.Amount,
                                        FiTransactionID = this.FiTransactionID,
                                        Note = this.Note,
                                        CurrencyID = this.CurrencyID,

                                        //Standard Fields
                                        StatusID = this.StatusID,
                                        CreatedBy = this.CreatedBy,
                                        CreatedOn = DateTime.Now,
                                        EditedBy = this.EditedBy,
                                        EditedOn = DateTime.Now
                                    };
                                    db.AddToFiCheque(editedItem);
                                }
                                else
                                {
                                    editedItem = (from xItem in db.FiCheque
                                                  where xItem.FiChequeID == this.FiChequeID
                                                  select xItem).First();
                                    if (editedItem.TStamp == this.Timestamp)
                                    {
                                        //Add++ //DDL++
                                        editedItem.FiscalYearID = this.FiscalYearID;
                                        editedItem.ChequeNo = this.ChequeNo;
                                        editedItem.Bank = this.Bank;
                                        editedItem.MyBank = this.MyBank;
                                        editedItem.ValueDate = this.ValueDate;
                                        editedItem.Amount = this.Amount;
                                        editedItem.FiTransactionID = this.FiTransactionID;
                                        editedItem.Note = this.Note;
                                        editedItem.CurrencyID = this.CurrencyID;


                                        //Standard Fields
                                        editedItem.StatusID = this.StatusID;
                                        editedItem.EditedBy = this.EditedBy;
                                        editedItem.EditedOn = DateTime.Now;
                                    }
                                    else
                                    {
                                        MessageStack.Add(new P2TransactionMessage("red", P2Translator.GetResource("TMsg_AccountNotUpdated"))); //--> rename it
                                    }
                                }
                                if (MessageStack.StatusMessage.MessageStatus != P2ValidationStatus.red)
                                {
                                    db.SaveChanges();
                                    ts.Complete();
                                    if (this.FiChequeID < 0)
                                    {
                                        this.FiChequeID = editedItem.FiChequeID;
                                    }
                                }
                            }
                        }

                        FillMyObject();
                    }
                    Modified = false;
                    if (MessageStack.StatusMessage.MessageStatus != P2ValidationStatus.red)
                    {
                        if (this.FiChequeID < 0)
                        {
                            MessageStack.Add(new P2TransactionMessage("green", P2Translator.GetResource("TMsg_ChequeAdded")));
                        }
                        else
                            MessageStack.Add(new P2TransactionMessage("green", P2Translator.GetResource("TMsg_ChequeUpdated")));
                    }

                }
            }
            catch (Exception ex)
            {
                MessageStack.Add(new P2TransactionMessage("red", P2Translator.GetResource("Error_Error")));
                P2ExceptionHandler.LogException(ex, this);
            }
            return MessageStack;
        }

        public void Cancel()
        {
            try
            {
                this.StatusID = 170502;
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (DAL.FiChequeDataContext db = new DAL.FiChequeDataContext(connectionString))
                {
                    var cheque = (from ch in db.FiCheque
                                       where ch.FiChequeID == this.FiChequeID
                                       select ch).First();
                    cheque.StatusID = this.StatusID;
                    db.SaveChanges();
                }

                this.FillMyObject();
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }

        public void Paid()
        {
            try
            {
                this.StatusID = 170503; //Status Open
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (DAL.FiChequeDataContext db = new DAL.FiChequeDataContext(connectionString))
                {
                    var cheque = (from ch in db.FiCheque
                                  where ch.FiChequeID == this.FiChequeID
                                  select ch).First();
                    cheque.StatusID = this.StatusID;
                    db.SaveChanges();
                }

                this.FillMyObject();
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        public void ReOpen()
        {
            try
            {
                this.StatusID = 170501; //Status Open
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (DAL.FiChequeDataContext db = new DAL.FiChequeDataContext(connectionString))
                {
                    var cheque = (from ch in db.FiCheque
                                  where ch.FiChequeID == this.FiChequeID
                                  select ch).First();
                    cheque.StatusID = this.StatusID;
                    db.SaveChanges();
                }

                this.FillMyObject();
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }

        public void Transfer()
        {
            try
            {
                this.StatusID = 170504; //Status Transferred
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (DAL.FiChequeDataContext db = new DAL.FiChequeDataContext(connectionString))
                {
                    var cheque = (from ch in db.FiCheque
                                  where ch.FiChequeID == this.FiChequeID
                                  select ch).First();
                    cheque.StatusID = this.StatusID;
                    db.SaveChanges();
                }

                this.FillMyObject();
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }
        #endregion       
     
       
        #region Property Changed

        public event PropertyChangedEventHandler PropertyChanged;


        private void OnPropertyChanged(string propertyName) 
        {
            Modified = true;
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null) Handler(this, new PropertyChangedEventArgs(propertyName));
        }

        //Add++ //DDL++
        public void OnAllPropertiesChanged() 
        {
            OnPropertyChanged("FiChequeID");
            OnPropertyChanged("FiscalYearID"); 
            OnPropertyChanged("ChequeNo"); 
            OnPropertyChanged("Bank");
            OnPropertyChanged("MyBank"); 
            OnPropertyChanged("ValueDate"); 
            OnPropertyChanged("Amount"); 
            OnPropertyChanged("FiTransactionID"); 
            OnPropertyChanged("Note");
            
            OnPropertyChanged("CurrencyID");             
                                 
            //Standard Fields
            OnPropertyChanged("StatusName");
            OnPropertyChanged("StatusID");
        }

        #endregion


        #region Validator

        public override P2Validator Validator
        {
            get
            {
                if (_validator == null)
                    _validator = new P2Validator(Properties.Settings.Default.ModuleName, this.EntityName, "FiChequeID", this);
                return _validator;
            }
        }

        #endregion


    }
}



